/**
 * 
 */
package com.ihome.framework.core.event.command.buffer;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;


import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ihome.framework.core.exception.PlatformException;
import com.ihome.framework.core.id.service.IdGeneratorService.UUIDWorker;
import com.ihome.framework.core.event.command.buffer.CommandBuffer.CommandDto;

/**
 * @author zww
 *
 */
public abstract class CommandBuffer<T extends CommandDto> {
    

    private final List<T> commandList;

    private final int capacity;
    
    private transient Logger LOGGER = LoggerFactory.getLogger(getClass());

    public CommandBuffer(int capacity){
        this.capacity = capacity;
        this.commandList = new ArrayList<T>(capacity);
    }

    
    public static abstract class SqlCommandDto extends CommandDto{

        public SqlCommandDto(String requestId) {
            super(requestId);
        }
        
        public abstract String toSql();
        
        
        /* (non-Javadoc)
         * @see com.ihome.framework.core.event.command.buffer.CommandBuffer.CommandDto#toString()
         */
        @Override
        public String toString() {
            return new StringBuffer("requestId:").append(getRequestId()).append("|sql:").append(toSql()).toString();
        }
        
        
    }
    

    public static abstract class CommandDto implements Serializable{

        private static final long serialVersionUID = -2463630580877588711L;
        protected final String id;
        protected final String requestId;


        /**
         * Command来源的requestId
         *
         * @param requestId
         */
        public CommandDto(String requestId) {
            this.id = UUIDWorker.getNextId();
            this.requestId = requestId;
        }

        /**
         * 全局唯一Id, uuid
         *
         * @return
         */
        public String getId() {
            return id;
        }

        /**
         * 对应的{@link RequestDto#id}
         *
         * @return
         */
        public String getRequestId() {
            return requestId;
        }
        
        /* (non-Javadoc)
         * @see java.lang.Object#toString()
         */
        @Override
        public String toString() {
            return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
        }
    }

    static class CommandBufferOverflowException extends PlatformException{

    }
    


    public static class CommandCollector {
        private final List<CommandDto> commandList = new ArrayList<>();

        public List<CommandDto> getCommandList() {
            return commandList;
        }
        public void addCommand(CommandDto command) {
            commandList.add(command);
        }
        
        
        public void clear(){
            commandList.clear();
        }
        
    }


    /**
     * Buffer是否已经满了
     *
     * @return
     */
    public boolean hasRemaining(){
        return commandList.size() < this.capacity;
    }

    /**
     * 放入Command
     *
     * @param command
     */
    public void put(T command){
        if (!hasRemaining()) {
            throw new CommandBufferOverflowException();
        }
        this.commandList.add(command);
    }

    /**
     * 清空缓存
     */
    public void clear(){
        commandList.clear();
    }

    /**
     * 获得{@link Command}
     *
     * @return
     */
    public  List<T> get(){
        return Collections.unmodifiableList(commandList);
    }
    
    @Override
    public String toString() {
        return super.toString()+"-"+ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }

}
